package cn.honglian.org.service.impl;

import cn.honglian.basic.config.BussinessException;
import cn.honglian.basic.dto.EmployeeDto;
import cn.honglian.basic.dto.ShopAuditLogDto;
import cn.honglian.basic.dto.ShopSettlementDto;
import cn.honglian.basic.eum.ShopStateEnum;
import cn.honglian.basic.service.impl.BaseServiceImpl;
import cn.honglian.basic.util.*;
import cn.honglian.basic.vo.ShopLogVo;
import cn.honglian.basic.vo.ShopStateAndCountVo;
import cn.honglian.basic.vo.ShopVo;
import cn.honglian.org.domain.Employee;
import cn.honglian.org.domain.Shop;
import cn.honglian.org.domain.ShopAuditLog;
import cn.honglian.org.mapper.EmployeeMapper;
import cn.honglian.org.mapper.ShopAuditLogMapper;
import cn.honglian.org.mapper.ShopMapper;
import cn.honglian.org.query.ShopQuery;
import cn.honglian.org.service.IShopService;
import cn.honglian.user.domain.Logininfo;
import cn.honglian.user.mapper.LogininfoMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;

import javax.mail.MessagingException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author honglian
 * @since 2022-11-20
 */
@Service
@Slf4j
public class ShopServiceImpl extends BaseServiceImpl<Shop> implements IShopService {

    @Autowired
    private ShopMapper shopMapper;

    @Autowired
    private EmployeeMapper employeeMapper;
    
    @Autowired
    private ShopAuditLogMapper shopAuditLogMapper;
    @Autowired
    private LogininfoMapper logininfoMapper;



    @Override
    public void settlement(ShopSettlementDto shopSettlementDto) {

            check(shopSettlementDto);

            save(shopSettlementDto);




    }

    private void save(ShopSettlementDto shopSettlementDto) {
        // 添加到数据库
        Shop shop1 = shopSettlementDto.getShop();
        shopMapper.add(shop1);
        Employee emp = shopSettlementDto.getEmp();
        emp.setShopId(shop1.getId());
        // 生成盐值
        String salt = StrUtils.getComplexRandomString(32);
        // 给盐值和密码加密
        String password = MD5Utils.encrypByMd5(salt+emp.getPassword());
        emp.setSalt(salt);
        emp.setPassword(password);
        employeeMapper.add(emp);
        // 同步到logininfo表内
        Logininfo logininfo = new Logininfo();
        BeanUtils.copyProperties(emp, logininfo);
        logininfo.setType(0);
        logininfo.setDisable(1);
        logininfoMapper.add(logininfo);
        emp.setLogininfoId(logininfo.getId());
        employeeMapper.update(emp);

        shop1.setAdminId(emp.getId());
        shopMapper.update(shop1);
    }

    private void check(ShopSettlementDto shopSettlementDto) {
        // 检验参数   注解完成

        // 判断二次密码是否相同
        EmployeeDto admin = shopSettlementDto.getAdmin();
        if (null != admin && !admin.getPassword().equals(admin.getComfirmPassword())) {
            throw new BussinessException("2次密码不相同");
        }
        // 判断店铺是否存在
        /*
        根据name判断
         */
        Shop shop = shopMapper.findByTel(shopSettlementDto.getTel());
        if (null != shop) {
            throw new BussinessException("店铺已存在");
        }
        // 判断员工是否为店长 根据username
        Employee employee = employeeMapper.findByName(admin.getUsername());
        if (null != employee && null != employee.getShopId()) {
            shop = shopMapper.findById(employee.getShopId());
            if (null != shop && shop.getAdminId().equals(employee.getId())) {
                throw new BussinessException("你已经是店长了适可而止把");
            }

        }


        // AI百度校验
        if (! BaiduAuditUtils.TextCensor(shopSettlementDto.getName())){
            throw new BussinessException("店铺名称不合法");
        }
        if (! BaiduAuditUtils.ImgCensor(shopSettlementDto.getLogo()) ||  null==shopSettlementDto.getLogo()){
            throw new BussinessException("店铺logo不合法");
        }
    }


    /*
    人工审核后店铺信息无误发送邮件给客户，让用户激活
     */
    @Override
    public void auditPass(ShopAuditLogDto shopAuditLogDto) throws MessagingException {
            // 修改状态
        Shop shop = updateState(shopAuditLogDto);
        // 添加到shop日志中
        addLog(shopAuditLogDto, shop);
        // 发送邮件
//        SendMail(shopAuditLog);
        EmailUtil.SendEMail("2642986435@qq.com","恭喜成功入驻本平台","<h1>恭喜您成为我们平台的一员，请点击下方链接，我们将为您激活店铺，之后你就可以在我们的平台添加你的商品了</h1>:http://localhost:8080/shop/active/"+shopAuditLogDto,"2642986435@qq.com");
    }
    /*
    人工审核后店铺信息有误发送邮件给客户
     */

    @Override
    public void auditReject(ShopAuditLogDto shopAuditLogDto) {
        // 修改状态
        Shop shop = updateState(shopAuditLogDto);
        // 添加到shop日志中
        addLog(shopAuditLogDto, shop);
        EmailUtil.SendEMail("2642986435@qq.com","你的店铺入驻被驳回","<h1>不好意思您的信息有误，请点击下方链接，重新入驻店铺</h1>http://localhost:8081/#/registerAgain?shopId="+shopAuditLogDto,"2642986435@qq.com");

    }

    /*

        店铺二次入驻
     */
    @Override
    public void settlementAgain(ShopSettlementDto shopSettlementDto) {
        if (! BaiduAuditUtils.TextCensor(shopSettlementDto.getName())){
            throw new BussinessException("店铺名称不合法");
        }
        if (! BaiduAuditUtils.ImgCensor(shopSettlementDto.getLogo())&& null!=shopSettlementDto.getLogo()){
            throw new BussinessException("店铺logo不合法");
        }
            Shop shop = shopSettlementDto.getShop();
            shop.setId(shopSettlementDto.getId());
            shop.setState(ShopStateEnum.WAIT_AUDIT.getCode());
            shopMapper.update(shop);


    }
    /*
    excel导入的批量添加
     */
    @Override
    public void addAll(List<Shop> shops) {
        shopMapper.addAll(shops);
    }
    /*
    报表的实现
     */
    @Override
    public ShopVo aharts() {
        List<ShopStateAndCountVo> echarts = shopMapper.aharts();
        List<Integer> x = echarts.stream().map(ShopStateAndCountVo::getState).collect(Collectors.toList());
        List<Integer> y = echarts.stream().map(ShopStateAndCountVo::getNum).collect(Collectors.toList());


        return  ShopVo.builder().x(x).y(y).build();
    }

    @Override
    public PageList<ShopLogVo> expandChange(ShopQuery query) {

        Integer totals = shopMapper.queryByCount(query);
        if (null == totals || 0 == totals) {
            return new PageList<ShopLogVo>(0, new ArrayList<>());
        }
        List<ShopLogVo> shopAll = shopMapper.queryByPagAndLogs(query);


        List<Long> ids = shopAll.stream().map(Shop::getId).collect(Collectors.toList());

       List<ShopAuditLog>  shopAuditLogts = shopAuditLogMapper.findByShopId(ids);
//        List<ShopAuditLog> shopAuditLogts = shopAuditLogMapper.findAll();
        Map<Long, List<ShopAuditLog>> map = shopAuditLogts.stream().collect(Collectors.groupingBy(ShopAuditLog::getShopId));

        for (ShopLogVo shop :shopAll) {
            List<ShopAuditLog> shopAuditLogs = map.get(shop.getId());
            shop.setAuditLogs(shopAuditLogs);
        }

        return new PageList<ShopLogVo>(totals,shopAll);
    }
    /*
       添加日志的方法抽取
     */
    private void addLog(ShopAuditLogDto shopAuditLogDto, Shop shop) {

        ShopAuditLog shopAuditLog1 = new ShopAuditLog();
        shopAuditLog1.setAuditTime(new Date());
        shopAuditLog1.setAuditId(1);
        shopAuditLog1.setNote(shopAuditLogDto.getNote());
        shopAuditLog1.setShopId(shop.getId());
        // 判断前端传来的type来给日志表里的字段赋值
        if(0==shopAuditLogDto.getType()){
            shopAuditLog1.setLogState(ShopStateEnum.ROLL_BACK.getCode());
        } else {
            shopAuditLog1.setLogState(ShopStateEnum.WAIT_ACTIVE.getCode());
        }
        shopAuditLogMapper.add(shopAuditLog1);
    }

    /*
    用户二次修改店铺数据的方法抽取
     */
    private Shop updateState(ShopAuditLogDto shopAuditLogDto) {
        // 修改状态
        Shop shop = new Shop();
        shop.setId(shopAuditLogDto.getShopId());
        if (shopAuditLogDto.getType()==1){
            shop.setState(ShopStateEnum.WAIT_ACTIVE.getCode());
        } else if (shopAuditLogDto.getType()==0){
            shop.setState(ShopStateEnum.ROLL_BACK.getCode());
        }

        shopMapper.update(shop);
        return shop;
    }
}
